Java将文件压缩成压缩包
关于java下载文件的时候, 多是把很多文件压缩成压缩包之后在下载, 之前在网上查了一些资料, 将文件压缩成压缩包, 里面还有复制文件或文件夹的方法,最近又使用到这个, 所以记录一下, 方便后续可能再次使用到。
代码片
.
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 将文件夹下面的文件
* 打包成zip压缩文件
*
*/
public final class FileToZip {
static int count = 0;
private FileToZip(){}
/**
* 将存放在sourceFilePath目录下的源文件,打包成fileName名称的zip文件,并存放到zipFilePath路径下
* @param sourceFilePath :待压缩的文件路径
* @param zipFilePath :压缩后存放路径
* @param fileName :压缩后文件的名称
* @return
*/
public static boolean fileToZip(String sourceFilePath, String zipFilePath,
String fileName){
boolean flag = false;
File sourceFile = new File(sourceFilePath);
FileInputStream fis = null;
BufferedInputStream bis = null;
FileOutputStream fos = null;
ZipOutputStream zos = null;
if(sourceFile.exists() == false){
System.out.println("待压缩的文件目录:"+sourceFilePath+"不存在.");
}else{
try {
File zipFile = new File(zipFilePath + "/" + fileName +".zip");
if(zipFile.exists()){
System.out.println(zipFilePath + "目录下存在名字为:" + fileName +".zip" +"打包文件.");
}else{
File[] sourceFiles = sourceFile.listFiles();
if(null == sourceFiles || sourceFiles.length<1){
System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
}else{
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(new BufferedOutputStream(fos));
byte[] bufs = new byte[1024*10];
for(int i=0;i<sourceFiles.length;i++){
//创建ZIP实体,并添加进压缩包
ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
zos.putNextEntry(zipEntry);
//读取待压缩的文件并写进压缩包里
fis = new FileInputStream(sourceFiles[i]);
bis = new BufferedInputStream(fis, 1024*10);
int read = 0;
while((read=bis.read(bufs, 0, 1024*10)) != -1){
zos.write(bufs,0,read);
}
bis.close();
fis.close();
}
flag = true;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally{
//关闭流
try {
if(null != bis) bis.close();
if(null != zos) zos.close();
if(null != fis) fis.close();
if(null != fos) fos.close();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
return flag;
}
/**
* 压缩成ZIP
* @param srcDir 压缩文件夹路径
* @param out 压缩文件输出流
* @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
* @throws RuntimeException 压缩失败会抛出运行时异常
*/
public static void toZip(String srcDir, OutputStream out,
boolean KeepDirStructure) throws RuntimeException {
long start = System.currentTimeMillis();
ZipOutputStream zos = null ;
try {
zos = new ZipOutputStream(out);
File sourceFile = new File(srcDir);
compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
long end = System.currentTimeMillis();
System.out.println("压缩完成,耗时:" + (end - start) +" ms");
} catch (Exception e) {
throw new RuntimeException("zip error from ZipUtils",e);
}finally{
if(zos != null){
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception{
byte[] buf = new byte[BUFFER_SIZE];
if(sourceFile.isFile()){
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1){
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if(listFiles == null || listFiles.length == 0){
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if(KeepDirStructure){
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
}else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (KeepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
} else {
compress(file, zos, file.getName(),KeepDirStructure);
}
}
}
}
}
/**
* 将压缩包删除
* @param file 压缩包文件
*/
public static boolean delDirectory(File file) {
if (file.isDirectory()) {
File[] files = file.listFiles();
for (File item : files) {
delDirectory(item);
}
}
return file.delete();
}
private static final int BUFFER_SIZE = 2 * 1024;
/**
* 复制文件(文件夹) 复制文件路径需要到文件名.后缀
* @param source 原文件 (File source = new File("原文件(文件夹)路径"))
* @param dest 复制后的目标路径
* @throws IOException
*/
public static void copyFile(File source, String dest) throws IOException {
//创建目的地文件夹
File destfile = new File(dest);
if (!destfile.exists()) {
destfile.mkdirs();
}
//如果source是文件夹,则在目的地址中创建新的文件夹
if (source.isDirectory()) {
File file = new File(dest+"\\"+source.getName());//用目的地址加上source的文件夹名称,创建新的文件夹
file.mkdir();
//得到source文件夹的所有文件及目录
File[] files = source.listFiles();
if (files.length==0) {
return;
} else {
for (int i = 0 ;i<files.length;i++) {
copyFile(files[i], file.getPath());
}
}
}
//source是文件,则用字节输入输出流复制文件
else if (source.isFile()) {
FileInputStream fis = new FileInputStream(source);
//创建新的文件,保存复制内容,文件名称与源文件名称一致
File dfile = new File(dest+"\\"+source.getName());
if (!dfile.exists()) {
dfile.createNewFile();
}
FileOutputStream fos = new FileOutputStream(dfile);
// 读写数据
// 定义数组
byte[] b = new byte[1024];
// 定义长度
int len;
// 循环读取
while ((len = fis.read(b))!=-1) {
// 写出数据
fos.write(b, 0 , len);
}
//关闭资源
fos.close();
fis.close();
}
}
public static void main(String[] args){
String sourceFilePath = "D:\\222";
String zipFilePath = "D:\\222";
String fileName = "333";
boolean flag = FileToZip.fileToZip(sourceFilePath, zipFilePath, fileName);
if(flag){
System.out.println("文件打包成功!");
}else{
System.out.println("文件打包失败!");
}
// 能压缩文件夹的
// FileOutputStream fos1 = new FileOutputStream(new File("D:\\222.zip"));
// toZip("D:\\222", fos1,true);
// 复制文件(文件夹)
// File source = new File("D:\\222.zip");
// String dest = "D:\\111";
// copyFile(source, dest)
}
}
可以把这个当成一个工具类, 方便后续使用。压缩成压缩包两个方法都可以使用, 第一个方法fileToZip, 不能把文件夹压缩, 只能压缩文件夹下的文件。第二个方法toZip, 可以把文件夹下的所有都压缩成压缩包(KeepDirStructure要设置成true才会有压缩前的结构)。 下载完成之后记得删除压缩包, 调用delDirectory方法即可。